﻿using MyX.Core;
using MyX.Work;
using MyX.Message;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyX.DSL
{
    public class WorkHelper
    {
        static WorkHelper()
        {

        }

        /// <summary>
        /// 设置通用异常处理函数
        /// <para> 当方法抛出异常，一定会调用该函数处理异常</para>
        /// <para>请保证该方法本身不会抛出异常</para>
        /// </summary>
        /// <param name="action"></param>
        public static void Exception(Action<Exception> action)
        {
            WorkTables.HandleWorks.Add(new XWorkStatusRun<XWorkStatus>(x =>
            {                
                if (!x.IsSuccess)
                    action(x.Exception);
            }));
        }

        public CommandWorkHelper<T> Command<T>(Action<T> action) where T : XCommand
        {
            var helper = new CommandWorkHelper<T>(this, action);
            _busHelper.Add(helper);
            return helper;
        }

        public EventWorkHelper<T> Event<T>(Action<T> action, bool canReplay = false) where T : XEvent
        {
            var helper = new EventWorkHelper<T>(this, action, canReplay);
            _busHelper.Add(helper);
            return helper;
        }


        private List<dynamic> _busHelper = new List<dynamic>();
    }

    public class CommandWorkHelper<T> where T : XCommand
    {
        public CommandWorkHelper(WorkHelper parent, Action<T> action)
        {
            _work = new XWorkRun<T>(action);
            WorkTables.CommandWorks.Add(_work);
            _parent = parent;
        }

        public WorkHelper End()
        {
            return _parent;
        }

        private XIWorkRun _work;
        private WorkHelper _parent;
    }

    public class EventWorkHelper<T> where T : XEvent
    {
        public EventWorkHelper(WorkHelper parent, Action<T> action, bool canReply)
        {
            WorkTables.EventWorks.Add(new XWorkRun<T>(action));

            //这里要记得重构
            if (canReply)
                XReplayManage.Register(new XReplayRun<T>(action));


            _parent = parent;

        }

        public WorkHelper End()
        {
            return _parent;
        }

        private WorkHelper _parent;
    }
}
